home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Overload Trio 2
/
Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO
/
dir27
/
calctool.zip
/
XVIEW.C
< prev
Wrap
C/C++ Source or Header
|
1992-09-09
|
19KB
|
670 lines
/* @(#)xview.c 1.11 89/12/21
*
* These are the XView dependent graphics routines used by calctool.
*
* Copyright (c) Rich Burridge.
* Sun Microsystems, Australia - All rights reserved.
*
* Permission is given to distribute these sources, as long as the
* copyright messages are not removed, and no monies are exchanged.
*
* No responsibility is taken for any errors or inaccuracies inherent
* either to the comments or the code of this program, but if
* reported to me then an attempt will be made to fix them.
*/
#include <stdio.h>
#include "calctool.h"
#include "color.h"
#include "extern.h"
#include <xview/xview.h>
#include <xview/canvas.h>
#include <xview/cms.h>
#include <xview/font.h>
#include <xview/cursor.h>
#include <xview/sel_svc.h>
#include <xview/sel_attrs.h>
#include <X11/Xlib.h>
#define MENU_SET (void) menu_set
#define NOTIFY_DO_DISPATCH (void) notify_do_dispatch
#define NOTIFY_INTERPOSE_DESTROY_FUNC (void) notify_interpose_destroy_func
#define SELN_QUERY (void) seln_query
#define XV_SET (void) xv_set
#define WINDOW_DONE (void) window_done
#define BIGFONT "lucidasanstypewriter-18"
#define DEFFONT "fixed"
#define NORMALFONT "lucidasanstypewriter-12"
#define SMALLFONT "lucidasanstypewriter-10"
void func_key_proc() ;
int menu_proc() ;
Canvas kcanvas, rcanvas ;
Canvas_paint_window cpw, rcpw ;
Event *cur_event ;
Frame frame, rframe ;
Icon calctool_icon ;
Menu menus[MAXMENUS] ;
Notify_value destroy_proc() ;
Seln_client sel_client ;
Seln_holder holder ;
Seln_rank rank = SELN_PRIMARY ;
Seln_result get_proc(), reply_proc() ;
Xv_Cursor help_cursor, main_cursor ;
Display *dpy ;
Drawable xid_cpw, xid_rcpw ;
GC gc ;
Window root ;
XColor current_col ;
XFontStruct *bfont, *font, *nfont, *sfont ;
XGCValues gc_val ;
unsigned long gc_mask ;
int screen ;
unsigned long backgnd, foregnd ;
unsigned long palette[CALC_COLORSIZE] ;
enum menu_type curmenu ; /* Current menu (if any) being processed. */
int started ; /* Set just before window is displayed. */
short help_cursor_array[16] = {
#include "help.cursor"
} ;
unsigned short icon_image[] = {
#include "calctool.icon"
} ;
short cicon_image[] = {
#include "calctool.color.icon"
} ;
mpr_static(cicon_pr, 64, 64, 8, cicon_image) ;
/*ARGSUSED*/
void
canvas_event_proc(canvas, event, arg)
Canvas canvas ;
Event *event ;
caddr_t arg ;
{
if (!started) return ;
cur_event = event ;
process_event(get_next_event(event)) ;
}
clear_canvas(ctype, color)
enum can_type ctype ;
int color ;
{
int x, y ;
unsigned int width, height, bwidth, depth ;
Window root, window ;
if (ctype == KEYCANVAS) window = xid_cpw ;
else if (ctype == REGCANVAS) window = xid_rcpw ;
XGetGeometry(dpy, window, &root, &x, &y, &width, &height, &bwidth, &depth) ;
if (iscolor) gc_val.foreground = palette[color] ;
else
{
if (color == WHITE) gc_val.foreground = backgnd ;
else gc_val.foreground = foregnd ;
}
gc_val.function = GXcopy ;
XChangeGC(dpy, gc, GCForeground | GCFunction, &gc_val) ;
XFillRectangle(dpy, window, gc, x, y, width, height) ;
}
close_frame()
{
if ((int) xv_get(rframe, XV_SHOW) == TRUE)
XV_SET(rframe, XV_SHOW, FALSE, 0) ;
XV_SET(frame, FRAME_CLOSED, TRUE, 0) ;
rstate = 0 ;
}
color_area(x, y, width, height, color)
int x, y, width, height, color ;
{
if (iscolor) gc_val.foreground = palette[color] ;
else
{
if (color == WHITE) gc_val.foreground = backgnd ;
else gc_val.foreground = foregnd ;
}
gc_val.function = GXcopy ;
XChangeGC(dpy, gc, GCForeground | GCFunction, &gc_val) ;
XFillRectangle(dpy, xid_cpw, gc, x, y,
(unsigned int) width, (unsigned int) height) ;
}
create_menu(mtype) /* Create popup menu for right button press. */
enum menu_type mtype ;
{
int i ;
menus[(int) mtype] = xv_create(XV_NULL, MENU_COMMAND_MENU,
MENU_NOTIFY_PROC, menu_proc,
0) ;
for (i = 0; i < MAXREGS; i++)
{
switch (mtype)
{
case M_ACC : /* Accuracies. */
case M_EXCH : /* Register exchange. */
case M_LSHIFT : /* Left shift. */
case M_RCL : /* Register recall. */
case M_RSHIFT : /* Right shift. */
case M_STO : MENU_SET(menus[(int) mtype], /* Register store. */
MENU_STRING_ITEM, num_names[i], i+1,
0) ;
break ;
case M_CON : if (strlen(con_names[i])) /* Constants. */
MENU_SET(menus[(int) mtype],
MENU_STRING_ITEM, con_names[i], i+1,
0) ;
break ;
case M_FUN : if (strlen(fun_names[i])) /* Functions. */
MENU_SET(menus[(int) mtype],
MENU_STRING_ITEM, fun_names[i], i+1,
0) ;
}
}
}
destroy_frame()
{
WINDOW_DONE(frame) ;
exit(0) ;
}
destroy_rframe(frame)
Frame frame ;
{
rstate = 0 ;
XV_SET(frame, XV_SHOW, FALSE, 0) ;
}
/*ARGSUSED*/
Notify_value
destroy_proc(client, status)
Notify_client client ;
Destroy_status status ;
{
exit(0) ;
}
/* This routine works rather strangely. Because menu_show does not block
* under XView, do_menu cannot return a valid selection. So the menu
* selection handling has been moved to the notification procedure, and
* the appropriate code in graphics.c has been isolated into a separate
* routine. All in all, a bit of a kludge.
*/
do_menu(mtype) /* Popup appropriate menu. */
enum menu_type mtype ;
{
curmenu = mtype ;
menu_show(menus[(int) mtype], kcanvas, cur_event, 0) ;
return(0) ;
}
drawline(x1, y1, x2, y2)
int x1, y1, x2, y2 ;
{
if (iscolor) gc_val.foreground = palette[BLACK] ;
else gc_val.foreground = foregnd ;
gc_val.function = GXcopy ;
XChangeGC(dpy, gc, GCForeground | GCFunction, &gc_val) ;
XDrawLine(dpy, xid_cpw, gc, x1, y1, x2, y2) ;
}
draw_regs()
{
Rect frect, rrect ;
make_registers() ;
/* Force the register popup to appear to the right of the main calctool
* frame if it's not already being displayed.
*/
if (xv_get(rframe, XV_SHOW)) return ;
frame_get_rect(frame, &frect) ;
frame_get_rect(rframe, &rrect) ;
rrect.r_left = frect.r_left + frect.r_width + 5 ;
rrect.r_top = frect.r_top + 21 ;
frame_set_rect(rframe, &rrect) ;
XV_SET(rframe, XV_SHOW, TRUE, 0) ;
}
drawtext(x, y, ctype, fontno, color, str)
enum font_type fontno ;
enum can_type ctype ;
int x, y, color ;
char *str ;
{
Drawable window ;
if (fontno == SFONT) font = sfont ;
else if (fontno == NFONT) font = nfont ;
else if (fontno == BFONT) font = bfont ;
if (ctype == KEYCANVAS) window = xid_cpw ;
else if (ctype == REGCANVAS) window = xid_rcpw ;
if (ctype == KEYCANVAS && y == items[(int) DISPLAYITEM].y) x += 70 ;
if (iscolor) gc_val.foreground = palette[color] ;
else
{
if (color == WHITE) gc_val.foreground = backgnd ;
else gc_val.foreground = foregnd ;
}
gc_val.font = font->fid ;
gc_val.function = GXcopy ;
XChangeGC(dpy, gc, GCFont | GCForeground | GCFunction, &gc_val) ;
XDrawString(dpy, window, gc, x, y, str, strlen(str)) ;
}
/*ARGSUSED*/
void
func_key_proc(client_data, args)
char *client_data ;
Seln_function_buffer *args ;
{
get_display() ;
}
get_display() /* The GET function key has been pressed. */
{
if (seln_acquire(sel_client, SELN_SHELF) == SELN_SHELF)
{
if (shelf != NULL) free(shelf) ;
shelf = malloc((unsigned) strlen(display)) ;
STRCPY(shelf, display) ; /* Safely keep copy of display. */
}
}
XFontStruct *
get_font(name)
char *name ;
{
XFontStruct *font ;
if (!(font = XLoadQueryFont(dpy, name)))
if (!(font = XLoadQueryFont(dpy, DEFFONT)))
{
perror("couldn't get the default font.") ;
exit(1) ;
}
return(font) ;
}
get_next_event(event)
Event *event ;
{
static char eb[4] ; /* Event buffer. */
int i ;
#ifdef SUN4_KEYBOARD
char *rpad = "\000\000\000=/*789456123" ;
#else
char *rpad = "*-+7894561230.=" ;
#endif /*SUN4_KEYBOARD*/
nextc = event_id(event) ;
curx = event_x(event) ;
cury = event_y(event) ;
if (event_is_button(event))
if (event_is_down(event) && nextc == MS_LEFT) return(LEFT_DOWN) ;
else if (event_is_down(event) && nextc == MS_MIDDLE) return(MIDDLE_DOWN) ;
else if (event_is_down(event) && nextc == MS_RIGHT) return(RIGHT_DOWN) ;
else if (event_is_up(event) && nextc == MS_LEFT) return(LEFT_UP) ;
else if (event_is_up(event) && nextc == MS_MIDDLE) return(MIDDLE_UP) ;
else if (event_is_up(event) && nextc == MS_RIGHT) return(RIGHT_UP) ;
if (event_is_ascii(event) && event_is_down(event))
{
/* With the Sun4 keyboard, the right function keypad generates key_right
* events except for the function keys which are not in the range R1-R15.
* These return ASCII values which are:
* INS (0) = 0, DEL (.) = 127, Enter = 13, - = 45, + = 43.
*
* These are correct except for INS and DEL. INS can be remapped to ASCII
* 48 (the digit zero), but there is no easy way to handle DEL remapping,
* If you remap DEL to ASCII 46 (decimal point), this also remaps the
* Delete key value. For now, this value is left alone.
*/
#ifdef SUN4_KEYBOARD
if (nextc == 0) nextc = 48 ; /* Remap INS (0) key. */
if (nextc == 127) nextc = 46 ; /* Remap DEL (.) key. */
#endif /*SUN4_KEYBOARD*/
/* All the rest of the ASCII characters. */
cur_ch = nextc ;
return(KEYBOARD) ;
}
if (event_is_key_right(event) && event_is_up(event))
{
for (i = 1; i < 16; i++)
if (nextc == KEY_RIGHT(i))
{
cur_ch = rpad[i-1] ;
return(KEYBOARD) ;
}
}
if (nextc == KBD_DONE && down) return(EXIT_WINDOW) ;
if (nextc == LOC_WINEXIT) return(EXIT_WINDOW) ;
if (nextc == LOC_WINENTER) return(ENTER_WINDOW) ;
if (nextc == WIN_RESIZE) return(CFRAME_REPAINT) ;
if (nextc == WIN_REPAINT) return(CFRAME_REPAINT) ;
if ((nextc == KEY_LEFT(6)) & event_is_up(event)) return(PUT_ON_SHELF) ;
if ((nextc == KEY_LEFT(8)) && event_is_up(event)) return(TAKE_FROM_SHELF) ;
return(LASTEVENTPLUSONE) ;
}
Seln_result
get_proc(buffer)
Seln_request *buffer ;
{
issel = 0 ;
if (*buffer->requester.context == 0)
{
if (buffer == (Seln_request *) NULL ||
*((Seln_attribute *) buffer->data) != SELN_REQ_CONTENTS_ASCII)
return ;
selection = buffer->data + sizeof(Seln_attribute) ;
*buffer->requester.context = 1 ;
}
else selection = buffer->data ;
issel = 1 ;
}
handle_selection() /* Handle the GET function key being pressed. */
{
char context = 0 ;
holder = seln_inquire(rank) ;
if (holder.state == SELN_NONE) return ;
SELN_QUERY(&holder, get_proc, &context, SELN_REQ_CONTENTS_ASCII, 0, 0) ;
}
init_fonts() /* Null routine; fonts loaded in make_subframes. */
{
}
init_ws_type()
{
gtype = XVIEW ;
started = 0 ; /* Kludge to correctly handle repaints. */
return 0 ;
}
load_colors() /* Create and load calctool color map. */
{
u_char red[CALC_COLORSIZE], green[CALC_COLORSIZE], blue[CALC_COLORSIZE] ;
int i, numcolors ;
iscolor = 0 ;
if (DisplayCells(dpy, screen) > 2)
{
calc_colorsetup(red, green, blue) ;
iscolor = 1 ;
numcolors = 0 ;
for (i = 0; i < CALC_COLORSIZE; i++)
{
current_col.flags = DoRed | DoGreen | DoBlue ;
current_col.red = (unsigned short) (red[i] << 8) ;
current_col.green = (unsigned short) (green[i] << 8) ;
current_col.blue = (unsigned short) (blue[i] << 8) ;
if (XAllocColor(dpy, DefaultColormap(dpy, screen), ¤t_col) == True)
palette[numcolors++] = current_col.pixel ;
}
if (numcolors < 2)
{
FPRINTF(stderr, "%s: cannot allocate colors.\n", progname) ;
exit(1) ;
}
}
}
make_frames(argc, argv)
int argc ;
char *argv[] ;
{
xv_init(XV_INIT_ARGS, argc, argv, 0) ;
frame = xv_create(0, FRAME,
FRAME_ICON, calctool_icon,
FRAME_SHOW_LABEL, FALSE,
FRAME_NO_CONFIRM, TRUE,
XV_WIDTH, TWIDTH,
XV_HEIGHT, THEIGHT + DISPLAY,
0) ;
iscolor = ((int) xv_get(frame, WIN_DEPTH) > 1) ? 1 : 0 ;
sel_client = seln_create(func_key_proc, reply_proc, (char *) 0) ;
NOTIFY_INTERPOSE_DESTROY_FUNC(frame, destroy_proc) ;
rframe = xv_create(frame, FRAME,
FRAME_SHOW_LABEL, FALSE,
FRAME_NO_CONFIRM, TRUE,
FRAME_DONE_PROC, destroy_rframe,
XV_X, TWIDTH + 15,
XV_Y, 0,
XV_SHOW, FALSE,
XV_WIDTH, TWIDTH,
XV_HEIGHT, 200,
XV_FONT, nfont,
0) ;
}
make_icon()
{
Server_image sv_image ;
sv_image = xv_create(XV_NULL, SERVER_IMAGE,
SERVER_IMAGE_BITS, icon_image,
SERVER_IMAGE_DEPTH, 1,
XV_WIDTH, 64,
XV_HEIGHT, 64,
0) ;
calctool_icon = xv_create(XV_NULL, ICON,
XV_WIDTH, ICONWIDTH,
ICON_IMAGE, sv_image,
0) ;
}
make_items()
{
Server_image help_pr ;
main_cursor = xv_get(kcanvas, WIN_CURSOR) ;
if (iscolor)
{
calctool_icon = (Icon) xv_get(frame, FRAME_ICON) ;
XV_SET(calctool_icon,
ICON_IMAGE, &cicon_pr,
0) ;
XV_SET(frame, FRAME_ICON, calctool_icon, 0) ;
}
help_pr = xv_create(XV_NULL, SERVER_IMAGE,
XV_WIDTH, 16,
XV_HEIGHT, 16,
SERVER_IMAGE_BITS, help_cursor_array,
0) ;
help_cursor = xv_create(NULL, CURSOR,
CURSOR_XHOT, 0,
CURSOR_YHOT, 0,
CURSOR_OP, PIX_SRC | PIX_DST,
CURSOR_IMAGE, help_pr,
0) ;
}
make_subframes()
{
rcanvas = xv_create(rframe, CANVAS, 0) ;
kcanvas = xv_create(frame, CANVAS,
CANVAS_RETAINED, FALSE,
OPENWIN_AUTO_CLEAR, FALSE,
XV_WIDTH, TWIDTH,
XV_HEIGHT, THEIGHT + DISPLAY,
XV_FONT, nfont,
CANVAS_PAINTWINDOW_ATTRS,
WIN_CONSUME_EVENTS,
MS_LEFT, MS_MIDDLE, MS_RIGHT,
WIN_ASCII_EVENTS, KBD_USE, KBD_DONE,
LOC_WINENTER, LOC_WINEXIT,
WIN_LEFT_KEYS, WIN_TOP_KEYS, WIN_RIGHT_KEYS,
0,
WIN_IGNORE_EVENTS,
LOC_MOVE, LOC_DRAG,
0,
WIN_EVENT_PROC, canvas_event_proc,
0,
0) ;
rcpw = canvas_paint_window(rcanvas) ;
cpw = canvas_paint_window(kcanvas) ;
dpy = (Display *) xv_get(frame, XV_DISPLAY) ;
xid_cpw = (Drawable) xv_get(cpw, XV_XID) ;
xid_rcpw = (Drawable) xv_get(rcpw, XV_XID) ;
screen = DefaultScreen(dpy) ;
root = RootWindow(dpy, screen) ;
foregnd = BlackPixel(dpy, screen) ;
backgnd = WhitePixel(dpy, screen) ;
gc_mask = GCForeground | GCBackground | GCGraphicsExposures ;
gc_val.foreground = foregnd ;
gc_val.background = backgnd ;
gc_val.graphics_exposures = False ;
gc = XCreateGC(dpy, root, gc_mask, &gc_val) ;
load_colors() ; /* Load the calctool colormap. */
bfont = get_font(BIGFONT) ;
nfont = get_font(NORMALFONT) ;
nfont_width = nfont->max_bounds.rbearing - nfont->min_bounds.lbearing ;
sfont = get_font(SMALLFONT) ;
}
/*ARGSUSED*/
menu_proc(menu, menu_item)
Menu menu ;
Menu_item menu_item ;
{
int choice ;
choice = (int) menu_get(menu_item, MENU_VALUE) ;
if (choice) handle_menu_selection(curmenu, choice) ;
}
/*ARGSUSED*/
Seln_result
reply_proc(item, context, length)
Seln_attribute item ;
Seln_replier_data *context ;
int length ;
{
int size ;
char *destp ;
switch (item)
{
case SELN_REQ_CONTENTS_ASCII :
if (context->context == NULL)
{
if (shelf == NULL) return(SELN_DIDNT_HAVE) ;
context->context = shelf ;
}
size = strlen(context->context) ;
destp = (char *) context->response_pointer ;
STRCPY(destp, context->context) ;
destp += size ;
while ((int) destp % 4 != 0) *destp++ = '\0' ;
context->response_pointer = (char **) destp ;
*context->response_pointer++ = 0 ;
return(SELN_SUCCESS) ;
case SELN_REQ_YIELD :
*context->response_pointer++ = (char *) SELN_SUCCESS ;
return(SELN_SUCCESS) ;
case SELN_REQ_BYTESIZE :
if (shelf == NULL) return(SELN_DIDNT_HAVE) ;
*context->response_pointer++ = (char *) strlen(shelf) ;
return(SELN_SUCCESS) ;
case SELN_REQ_END_REQUEST : return(SELN_SUCCESS) ;
default : return(SELN_UNRECOGNIZED) ;
}
}
set_cursor(type)
int type ;
{
switch (type)
{
case HELPCURSOR : XV_SET(cpw, WIN_CURSOR, help_cursor, 0) ;
break ;
case MAINCURSOR : XV_SET(cpw, WIN_CURSOR, main_cursor, 0) ;
}
}
start_tool()
{
started = 1 ;
xv_main_loop(frame) ;
}
toggle_reg_canvas()
{
rstate = !rstate ;
if (rstate) draw_regs() ;
else XV_SET(rframe, XV_SHOW, FALSE, 0) ;
}